/* semLibP.h - private semaphore library header file */

/*
 * Copyright (c) 1984-2005 Wind River Systems, Inc.
 *
 * The right to copy, distribute or otherwise make use of this software
 * may be licensed only pursuant to the terms of an applicable Wind River
 * license agreement. 
 */

/*
modification history
--------------------
02b,13oct05,yvp  Changes text of deprecated messages - use semXInitialize.
02a,26aug05,gls  fixed pSemExt index comment (SPR #111547)
01z,04aug05,gls  added read/write semaphore support
01y,04aug05,yvp  Added prototype for create/delete library init.
01x,07jun05,yvp  Updated copyright. #include now with angle-brackets.
01w,12apr05,kk   start deprecation of semXCoreInit() and semQInit().
01v,28sep04,fr   removed vSemCreate prototype (SPR 101349)
01u,10sep04,fr   declared semCreateTbl (SPR 101247)
01t,22mar04,dcc  added vSemCreate prototype.
01s,09mar04,dcc  updated SEMAPHORE offsets.
01r,08mar04,aeg  removed Diab _WRS_DEPRECATED C++ workaround.
01q,02mar04,aeg  deprecated semOLib APIs.
01p,31oct03,md   Added semMTakeByProxy
01p,26aug03,tcr  remove WindView InstClassId
01o,31oct03,dcc  updated semaphore offset comments, as a result of OBJ_CORE 
		 expansion.
01n,29oct03,pcm  implemented changes from code review
01m,20oct03,pcm  added new SEMAPHORE field
01l,05sep03,dcc  moved SEM_TYPE definitions to semLibCommon.h
01k,30may03,to   added offset SEM_CLASS_ID for optimized semaphore routine.
		 deleted K&R style prototypes.
01j,09apr03,ymz  update semaphore offset due to OBJ_CORE change
01i,17oct01,bwa  Corrected ASM offsets for events. Added SEM_M_SEND_EVENTS
		 definition.
01h,06sep01,bwa  Added VxWorks events support.
01g,19may97,jpd  made SEM_TYPE_MASK available from assembler files.
01f,10jul96,dbt  moved declaration of semMGiveForce to semLib.h (SPR #4352).
		 Updated copyright.
01e,10dec93,smb  added instrument class
01d,22sep92,rrr  added support for c++
01c,27jul92,jcf  changed semMTakeKern to semMPendQPut.
01b,19jul92,pme  added external declaration of shared sem show routine.
01a,04jul92,jcf  created.
*/

#ifndef __INCsemLibPh
#define __INCsemLibPh

#ifdef __cplusplus
extern "C" {
#endif

#ifndef	_ASMLANGUAGE
#include <vxWorks.h>
#include <vwModNum.h>
#include <semLib.h>
#include <qLib.h>
#include <private/classLibP.h>
#include <private/objLibP.h>
#include <private/eventLibP.h>
#include <stdarg.h>

/* semaphore types */

#define MAX_SEM_TYPE		8	/* maximum # of sem classes */

#endif /* !_ASMLANGUAGE */
#define SEM_TYPE_MASK		0x7	/* semaphore class mask */
#ifndef	_ASMLANGUAGE

typedef struct semaphore /* SEMAPHORE */
    {
    OBJ_CORE	objCore;	/* 0x00: object management */
    UINT8	semType;	/* 0x40: semaphore type */
    UINT8	options;	/* 0x41: semaphore options */
    UINT16	recurse;	/* 0x42: semaphore recursive take count */
    Q_HEAD	qHead;		/* 0x44: blocked task queue head */
    union
	{
	UINT		 count;	/* 0x54: current state */
	struct windTcb * owner;	/* 0x54: current state */
	} state;
    EVENTS_RSRC	events;		/* 0x58: VxWorks events */
    BOOL	priInheritFlag;	/* 0x64: TRUE if sem involved in inheritance */
    void *      pSemExt;        /* 0x68: semaphore extension pointer */
    } SEMAPHORE;

typedef struct semRWExtention   /* SEM_RW_EXT */
    {
    UINT        readCount;      /* 0x00: current reader count */
    Q_HEAD      readQHead;      /* 0x04: blocked task queue head */
    Q_HEAD      upgradeQHead;   /* 0x14: blocked task queue head */
    } SEM_RW_EXT;

#define semCount	state.count
#define semOwner	state.owner

#define SEM_RW_OPTIONS_MASK    (SEM_BIN_OPTIONS_MASK |         \
                                SEM_DELETE_SAFE)

typedef enum		        /* SEM_RW_MODE */
    {
    SEM_RW_READ,		/* 0: read mode */
    SEM_RW_WRITE,		/* 1: write mode */
    SEM_RW_UPGRADE		/* 2: upgrade mode */
    } SEM_RW_MODE;

/*******************************************************************************
*
* SEMRW_EXT_PTR_GET - return the read/write semaphore extension pointer
*
* RETURNS: A pointer to the read/write semaphore extension
*
* SEM_RW_EXT * SEMRW_EXT_PTR_GET (SEM_ID semId)
*
* \NOMANUAL
*/

#define SEMRW_EXT_PTR_GET(semId) ((SEM_RW_EXT *) semId->pSemExt)

/*******************************************************************************
*
* SEMRW_READ_CNT - return the read/write semaphore read count
*
* RETURNS: The read/write semaphore read count
*
* UINT SEMRW_READ_CNT (SEM_ID semId)
*
* \NOMANUAL
*/

#define SEMRW_READ_CNT(semId) (((SEM_RW_EXT *) semId->pSemExt)->readCount)

/*******************************************************************************
*
* SEMRW_UQHEAD - return the read/write semaphore upgrade queue head
*
* RETURNS: The read/write semaphore upgrade queue head
*
* Q_HEAD SEMRW_UQHEAD (SEM_ID semId)
*
* \NOMANUAL
*/

#define SEMRW_UQHEAD(semId) (((SEM_RW_EXT *) semId->pSemExt)->upgradeQHead)

/*******************************************************************************
*
* SEMRW_RQHEAD - return the read/write semaphore read queue head
*
* RETURNS: The read/write semaphore read queue head
*
* Q_HEAD SEMRW_RQHEAD (SEM_ID semId)
*
* \NOMANUAL
*/

#define SEMRW_RQHEAD(semId) (((SEM_RW_EXT *) semId->pSemExt)->readQHead)

/*******************************************************************************
*
* SEMRW_IS_FREE - check if a read/write semaphore is free
*
* RETURNS: TRUE if the semaphore is free, FALSE if not.
*
* BOOL SEMC_IS_FREE (SEM_ID semId)
*
* \NOMANUAL
*/

#define SEMRW_IS_FREE(semId)                                         \
         (                                                           \
          (((semId)->semOwner == NULL) &&                            \
	   (((SEM_RW_EXT *) (semId)->pSemExt)->readCount == 0))      \
         )

/*******************************************************************************
*
* SEMC_IS_FREE - check if a counting semaphore is free
*
* RETURNS: TRUE if the semaphore is free, FALSE if not.
*
* BOOL SEMC_IS_FREE (SEM_ID semId)
*
* \NOMANUAL
*/

#define SEMC_IS_FREE(semId) (semId->semCount > 0)

/*******************************************************************************
*
* SEMBM_IS_FREE - check if a binary or mutex semaphore is free
*
* RETURNS: TRUE if the semaphore is free, FALSE if not.
*
* BOOL SEMBM_IS_FREE (SEM_ID semId)
*
* \NOMANUAL
*/

#define SEMBM_IS_FREE(semId) (semId->semOwner == NULL)

/* variable declarations */

extern OBJ_CLASS	semClass;		/* semaphore object class */
extern CLASS_ID		semClassId;		/* semaphore class id */
extern FUNCPTR		semCreateTbl [];	/* semCreate() methods */
extern FUNCPTR		semGiveTbl [];		/* semGive() methods */
extern FUNCPTR		semTakeTbl [];		/* semTake() methods */
extern FUNCPTR		semFlushTbl [];		/* semFlush() methods */
extern FUNCPTR		semGiveDeferTbl [];	/* semGiveDefer() methods */
extern FUNCPTR		semFlushDeferTbl [];	/* semFlushDefer() methods */
extern int		semMGiveKernWork;	/* semMGiveKern() parameter */

extern FUNCPTR  semSmShowRtn;	/* shared semaphore show routine pointer */
extern FUNCPTR  semSmInfoRtn;	/* shared semaphore info routine pointer */

/* function declarations */

extern STATUS	semLibInit (void);
extern void	semDeleteLibInit (void);
extern void	semBCreateLibInit (void);
extern void	semCCreateLibInit (void);
extern void	semMCreateLibInit (void);
extern void	semRWCreateLibInit (void);
extern STATUS	semTerminate (SEM_ID semId);
extern STATUS	semDestroy (SEM_ID semId, BOOL dealloc);
extern STATUS	semGiveDefer (SEM_ID semId);
extern STATUS	semFlushDefer (SEM_ID semId);
extern STATUS	semInvalid (SEM_ID semId);
extern STATUS	semIntRestrict (SEM_ID semId);
extern STATUS	semQFlush (SEM_ID semId);
extern void	semQFlushDefer (SEM_ID semId);
extern STATUS	semBInit (SEMAPHORE *pSem,int options,SEM_B_STATE initialState);
extern STATUS	semBGive (SEM_ID semId);
extern STATUS	semBTake (SEM_ID semId, int timeout);
extern void	semBGiveDefer (SEM_ID semId);
extern STATUS	semMInit (SEMAPHORE *pSem, int options);
extern STATUS	semMGive (SEM_ID semId);
extern STATUS	semMTake (SEM_ID semId, int timeout);
extern STATUS	semMTakeByProxy (SEM_ID semId, int tid);
extern STATUS	semMGiveKern (SEM_ID semId);
extern STATUS	semMPendQPut (SEM_ID semId, int timeout);
extern STATUS	semCInit (SEMAPHORE *pSem,int options,int initialCount);
extern STATUS	semCGive (SEM_ID semId);
extern STATUS	semCTake (SEM_ID semId, int timeout);
extern void	semCGiveDefer (SEM_ID semId);
extern STATUS 	semRWLibInit (void);
extern SEM_ID	semRWCreate (int options);
extern STATUS	semRWInit (SEMAPHORE * pSemaphore, int options);
extern STATUS	semRWGive (SEM_ID semId);
extern STATUS	semRWTake (SEM_ID semId, int timeout, int type);
extern STATUS	semRTake (SEM_ID semId, int timeout);
extern STATUS	semWTake (SEM_ID semId, int timeout);
extern STATUS	semRUTake (SEM_ID semId, int timeout);

/* workaround Diab handling of deprecated attribute in C++ */

extern STATUS	semOTake (SEM_ID semId) _WRS_DEPRECATED ("please use semBLib instead");
extern STATUS	semBCoreInit (SEMAPHORE *pSemaphore, 
			      int options, 
			      SEM_B_STATE initialState) _WRS_DEPRECATED ("please use semBInitialize() instead");

extern STATUS	semCCoreInit (SEMAPHORE *pSemaphore, 
			      int options, 
			      int initialCount) _WRS_DEPRECATED ("please use semCInitialize() instead");

extern STATUS	semMCoreInit (SEMAPHORE *pSemaphore, 
			      int options) _WRS_DEPRECATED ("please use semMInitialize() instead");

extern STATUS	semQInit (SEMAPHORE *pSemaphore, 
			  int options) _WRS_DEPRECATED ("please use semXInitialize() for the specific semaphore type instead");

#else	/* _ASMLANGUAGE */

/* offsets into SEMAPHORE */

#define	SEM_CLASS_ID		WIND_OBJ_CORE_CLASS_ID		/* 0x30 */
#define	SEM_TYPE		WIND_OBJ_CORE_SIZE		/* 0x40 */
#define	SEM_OPTIONS		(WIND_OBJ_CORE_SIZE + 0x01)	/* 0x41 */
#define	SEM_RECURSE		(WIND_OBJ_CORE_SIZE + 0x02)	/* 0x42 */
#define	SEM_Q_HEAD		(WIND_OBJ_CORE_SIZE + 0x04)	/* 0x44 */
#define	SEM_STATE		(WIND_OBJ_CORE_SIZE + 0x14)	/* 0x54 */
#define	SEM_EVENTS		(WIND_OBJ_CORE_SIZE + 0x18)	/* 0x58 */
#define	SEM_EVENTS_REGISTERED	(WIND_OBJ_CORE_SIZE + 0x18)	/* 0x58 */
#define	SEM_EVENTS_TASKID	(WIND_OBJ_CORE_SIZE + 0x1c)	/* 0x5c */
#define	SEM_EVENTS_OPTIONS	(WIND_OBJ_CORE_SIZE + 0x20)	/* 0x60 */
#define	SEM_PRI_INHERIT_FLAG	(WIND_OBJ_CORE_SIZE + 0x24)	/* 0x64 */

#define	SEM_INST_RTN		(WIND_CLASS_INST_RTN)		/* 0x1c */

#endif	/* _ASMLANGUAGE */

#define SEM_M_Q_GET		0x1		/* semMGiveKernWork() defines */
#define SEM_M_SAFE_Q_FLUSH	0x2
#define SEM_M_PRI_RESORT	0x4
#define SEM_M_SEND_EVENTS	0x8

#ifdef __cplusplus
}
#endif

#endif /* __INCsemLibPh */
